<?
/**
 * Copyright 2007 Melange.
 *
 * This file is part of PHP-AAS.
 *
 * PHP-AAS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * PHP-AAS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PHP-AAS; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @category    Melange
 * @package     php-aas
 * @subpackage  users
 * @copyright   Copyright (c) 2007 Jeroen Simons. All rights reserved
 * @author      Jeroen Simons <jeroen@melange.nl>
 * @link        http://www.melange.nl/
 *
 */

require_once("aas/MemoryRole.php");
require_once("aas/MemoryUser.php");
require_once("aas/MemoryGroup.php");

/**
 * <p>Concrete implementation of {@link UserDatabase} that loads all
 * defined users, groups, and roles into an in-memory data structure,
 * and uses a specified XML file for its persistent storage.</p>
 */

class MemoryUserDatabase {


    /**
     * The set of {@link Group}s defined in this database, keyed by
     * group name.
     */
    protected $groups = array();


    /**
     * The unique global identifier of this user database.
     */
    protected $id = null;


    /**
     * The relative (to <code>catalina.base</code>) or absolute pathname to
     * the XML file in which we will save our persistent information.
     */
    protected $pathname = "resources/phpmvc-users.xml";


    /**
     * The set of {@link Role}s defined in this database, keyed by
     * role name.
     */
    protected $roles = array();


    /**
     * The set of {@link User}s defined in this database, keyed by
     * user name.
     */
    protected $users = array();


    public function __construct($id = null) {
        $this->id = $id;
    }


    // ------------------------------------------------------------- Properties


    /**
     * Return the set of {@link Group}s defined in this user database.
     */
    public function getGroups() {
        return array_values($this->groups);
    }


    /**
     * Return the unique global identifier of this user database.
     */
    public function getId() {
        return ($this->id);
    }


    /**
     * Return the relative or absolute pathname to the persistent storage file.
     */
    public function getPathname() {
        return ($this->pathname);

    }


    /**
     * Set the relative or absolute pathname to the persistent storage file.
     *
     * @param pathname The new pathname
     */
    public function setPathname($pathname) {
        $this->pathname = $pathname;
    }


    /**
     * Return the set of {@link Role}s defined in this user database.
     */
    public function getRoles() {
        return array_values($this->roles);
    }


    /**
     * Return the set of {@link User}s defined in this user database.
     */
    public function getUsers() {
        return array_values($this->users);
    }



    // --------------------------------------------------------- Public Methods


    /**
     * Finalize access to this user database.
     *
     * @exception Exception if any exception is thrown during closing
     */
    public function close() {
        unset($this->users);
        unset($this->groups);
    }


    /**
     * Create and return a new {@link Group} defined in this user database.
     *
     * @param groupname The group name of the new group (must be unique)
     * @param description The description of this group
     */
    public function createGroup($groupname, $description) {
        $group = new MemoryGroup($this, $groupname, $description);
        $this->groups[$group->getGroupname()] = $group;
        return ($group);

    }


    /**
     * Create and return a new {@link Role} defined in this user database.
     *
     * @param rolename The role name of the new group (must be unique)
     * @param description The description of this group
     */
    public function createRole($rolename, $description) {
        $role = new MemoryRole($this, $rolename, $description);
        $this->roles[$role->getRolename()] = $role;
        return ($role);
    }


    /**
     * Create and return a new {@link User} defined in this user database.
     *
     * @param username The logon username of the new user (must be unique)
     * @param password The logon password of the new user
     * @param fullName The full name of the new user
     */
    public function createUser($username, $password, $fullName) {
        $user = new MemoryUser($this, $username, $password, $fullName);
        $this->users[$user->getUsername()] = $user;
        return (user);

    }


    /**
     * Return the {@link Group} with the specified group name, if any;
     * otherwise return <code>null</code>.
     *
     * @param groupname Name of the group to return
     */
    public function findGroup($groupname) {
        return array_key_exists($groupname, $this->groups) ?
            $this->groups[$groupname] : null;
    }


    /**
     * Return the {@link Role} with the specified role name, if any;
     * otherwise return <code>null</code>.
     *
     * @param rolename Name of the role to return
     */
    public function findRole($rolename) {
        return array_key_exists($rolename, $this->roles) ?
            $this->roles[$rolename] : null;
    }


    /**
     * Return the {@link User} with the specified user name, if any;
     * otherwise return <code>null</code>.
     *
     * @param username Name of the user to return
     */
    public function findUser($username) {
        return array_key_exists($username, $this->users) ?
            $this->users[$username] : null;
    }


    /**
     * Initialize access to this user database.
     *
     * @exception Exception if any exception is thrown during opening
     */
    public function open() {

        // Erase any previous groups and users
        $this->users = array();
        $this->groups = array();
        $this->roles = array();

        // Construct a reader for the XML input file (if it exists)
        if (!file_exists($this->pathname)) {
            return;
        }

        $dom = new DomDocument();
        if(!$dom->load($this->pathname)) {
            echo "Error while parsing the document\n";
            exit;
        }

        // Todo: Implement me!


    }


    /**
     * Remove the specified {@link Group} from this user database.
     *
     * @param group The group to be removed
     */
    public function removeGroup(Group $group) {

    }


    /**
     * Remove the specified {@link Role} from this user database.
     *
     * @param role The role to be removed
     */
    public function removeRole(Role $role) {

    }


    /**
     * Remove the specified {@link User} from this user database.
     *
     * @param user The user to be removed
     */
    public function removeUser(User $user) {
    }


    /**
     * Save any updated information to the persistent storage location for
     * this user database.
     *
     * @exception Exception if any exception is thrown during saving
     */
    public function save() {
    }


    /**
     * Return a String representation of this UserDatabase.
     */
    public function __toString() {

        $sb =  "MemoryUserDatabase[id=";
        $sb .= $this->id;
        $sb .= ",pathname=";
        $sb .= $this->pathname;
        $sb .= ",groupCount=";
        $sb .= count($this->groups);
        $sb .= ",roleCount=";
        $sb .= count($this->roles);
        $sb .= ",userCount=";
        $sb .= count($this->users);
        $sb .= "]";
        return ($sb);

    }

}
?>